package com.sxbbc.common.basics.wx.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sxbbc.common.basics.exceptions.ThrowJsonException;

/**
 * 公众平台通用接口工具类
 * @author Administrator
 *
 */
public class WeixinUtil{
	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            conn.setRequestMethod(requestMethod);
            conn.setRequestProperty("Charsert", "UTF-8");
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            return buffer.toString();
        } catch (ConnectException ce) {
            System.out.println("连接超时：{}"+ce);
        } catch (Exception e) {
        	System.out.println("https请求异常：{}"+ e);
        }
        return null;
    }
	public static String Unifiedorder(String requestXML){
		String requestUrl="https://api.mch.weixin.qq.com/pay/unifiedorder";
		String result =httpsRequest(requestUrl, "POST", requestXML);
		return result;
	}
	
	public static String Unifiedorder_query(String requestXML){
		String requestUrl="https://api.mch.weixin.qq.com/pay/orderquery";
		String result =httpsRequest(requestUrl, "POST", requestXML);
		return result;
	}
	
	public static String Unifiedorder_shouying(String requestXML){
		String requestUrl="https://api.mch.weixin.qq.com/pay/micropay";
		String result =httpsRequest(requestUrl, "POST", requestXML);
		return result;
	}
	
	public static String Unifiedorder_refund(String requestXML){
		String requestUrl="https://api.mch.weixin.qq.com/secapi/pay/refund";
		String result =httpsRequest(requestUrl, "POST", requestXML);
		return result;
	}
	
	/**
     * 将xml转化为Map集合
     * 
     * @param request
     * @return
     */
//    public static Map<String, String> xmlToMap(HttpServletRequest request) {
//        Map<String, String> map = new HashMap<String, String>();
//        SAXReader reader = new SAXReader();
//        InputStream ins = null;
//        try {
//            ins = request.getInputStream();
//        } catch (IOException e1) {
//            e1.printStackTrace();
//        }
//        Document doc = null;
//        try {
//            doc = reader.read(ins);
//        } catch (DocumentException e1) {
//            e1.printStackTrace();
//        }
//        Element root = doc.getRootElement();
//        @SuppressWarnings("unchecked")
//        List<Element> list = root.elements();
//        for (Element e : list) {
//            map.put(e.getName(), e.getText());
//        }
//        try {
//            ins.close();
//        } catch (IOException e1) {
//            e1.printStackTrace();
//        }
//        return map;
//    }
    
    public static Map<String, String> xmlToMap(HttpServletRequest request) {
    	try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilder documentBuilder = newDocumentBuilder();
            InputStream stream = request.getInputStream();
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            throw new ThrowJsonException("解析xml失败");
        }
    }
    
    public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
        documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        documentBuilderFactory.setXIncludeAware(false);
        documentBuilderFactory.setExpandEntityReferences(false);

        return documentBuilderFactory.newDocumentBuilder();
    }
}
